Agora que você tem um modelo treinado com Keras normal, está pronto para servir algumas previsões privadas. Podemos fazer isso usando o Syft Keras.
Para proteger e servir esse modelo, precisaremos de três TFEWorkers (servidores). Isso ocorre porque o TF Encrypted por debaixo dos panos usa uma técnica de criptografia chamada multi-party computation (MPC). A idéia é dividir os pesos do modelo e dados de entrada em partições, depois enviar uma parte de cada valor para os diferentes servidores. A propriedade-chave é que, se você observar a parte recebida em um servidor, ele não revelará nada sobre o valor original (dados de entrada ou pesos do modelo).
Definiremos um modelo Syft Keras como fizemos no notebook anterior. No entanto, há um truque: antes de instanciar esse modelo, executaremos hook = sy.KerasHook(tf.keras)
. Isso adicionará três novos métodos importantes à classe Sequencial Keras:
share
: protegerá seu modelo via compartilhamento secreto; por padrão, ele usará o protocolo SecureNN do TF Encrypted para compartilhar seu modelo em segredo entre cada um dos três TFEWorkers. Mais importante, isso adicionará a capacidade de fornecer previsões sobre dados criptografados.serve
: esta função irá lançar uma fila para servir, de modo que os TFEWorkers pode aceitar pedidos de previsão sobre o modelo seguro de clientes externos.shutdown_workers
: depois de fornecer previsões particulares, você pode desligar o modelo executando esta função. Ele o instruirá a encerrar os processos do servidor manualmente, se você optar por gerenciar manualmente cada worker.Se você quiser saber mais sobre o MPC, pode ler este excelente blog.
In [ ]:
import numpy as np
import tensorflow as tf
from tensorflow.keras import Sequential
from tensorflow.keras.layers import AveragePooling2D, Conv2D, Dense, Activation, Flatten, ReLU, Activation
import syft as sy
hook = sy.KerasHook(tf.keras)
Como você pode ver, definimos quase exatamente o mesmo modelo de antes, exceto que fornecemos um batch_input_shape
. Isso permite que o TF Encrypted otimize melhor os cálculos seguros através de formas predefinidas de tensores. Para esta demonstração MNIST, enviaremos dados de entrada com a forma (1, 28, 28, 1).
Também retornamos o logit em vez de softmax porque essa operação é complexa para executar usando MPC e não precisamos dela para atender a solicitações de previsão.
In [ ]:
num_classes = 10
input_shape = (1, 28, 28, 1)
In [ ]:
model = Sequential()
model.add(Conv2D(10, (3, 3), batch_input_shape=input_shape))
model.add(AveragePooling2D((2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(32, (3, 3)))
model.add(AveragePooling2D((2, 2)))
model.add(Activation('relu'))
model.add(Conv2D(64, (3, 3)))
model.add(AveragePooling2D((2, 2)))
model.add(Activation('relu'))
model.add(Flatten())
model.add(Dense(num_classes, name="logit"))
Com a função load_weights
, você pode carregar facilmente os pesos que você salvou anteriormente após treinar seu modelo.
In [ ]:
pre_trained_weights = 'short-conv-mnist.h5'
model.load_weights(pre_trained_weights)
Vamos agora criar TFEWorkers (alice
,bob
e carol
) exigidos pelo TF Encrypted para realizar previsões privadas. Para cada TFEWorker, você apenas precisa especificar um host. Em seguida, fazemos combinar esses workers em um cluster.
Esses trabalhadores executam um servidor TensorFlow, que você pode gerenciar manualmente (AUTO = False
) ou pedir aos workers que gerenciem para você (AUTO = True
). Se optar por gerenciá-los manualmente, você será instruído a executar um comando de terminal no dispositivo host de cada trabalhador após chamar cluster.start()
abaixo. Se todos os workers estiverem hospedados em um único dispositivo (por exemplo, localhost
), você poderá escolher que o Syft gerencie automaticamente o servidor TensorFlow do worker.
In [ ]:
AUTO = False
alice = sy.TFEWorker(host='localhost:4000', auto_managed=AUTO)
bob = sy.TFEWorker(host='localhost:4001', auto_managed=AUTO)
carol = sy.TFEWorker(host='localhost:4002', auto_managed=AUTO)
cluster = sy.TFECluster(alice, bob, carol)
cluster.start()
Graças ao sy.KerasHook (tf.keras)
, você pode chamar o método share
para transformar seu modelo em um modelo TF Encrypted Keras.
Se você pediu para gerenciar manualmente os servidores acima, essa etapa não será concluída até que todos tenham sido iniciados. Observe que seu firewall pode solicitar que o Python aceite a conexão de entrada.
In [ ]:
model.share(cluster)
Perfeito! Agora, chamando model.serve
, seu modelo está pronto para fornecer algumas previsões privadas. Você pode definir num_requests
para definir um limite para o número de requisições de previsões atendidas pelo modelo; se não especificado, o modelo será servido até ser interrompido.
In [ ]:
model.serve(num_requests=3)
Você está pronto para ir para o notebook Parte 13c para fazer requisições de algumas previsões privadas.
Quando o limite de suas requisições for totalmente utilizado, o modelo não estará mais disponível para atender requisições, mas ainda será compartilhado em segredo entre os três workers acima. Você pode matar os workers executando a célula abaixo.
Parabéns por concluir a Parte 13b: Classificação segura com Syft Keras e TFE!
In [ ]:
model.stop()
cluster.stop()
if not AUTO:
process_ids = !ps aux | grep '[p]ython -m tf_encrypted.player --config' | awk '{print $2}'
for process_id in process_ids:
!kill {process_id}
print("Process ID {id} has been killed.".format(id=process_id))
In [ ]: